package com.un.ebs.core.security;

import com.un.ebs.context.service.TokenService;
import com.un.ebs.core.config.ErrorCodes;
import com.un.ebs.core.exception.SystemException;
import com.un.ebs.core.util.JwtUtils;
import com.un.ebs.core.util.SpringContextUtil;
import com.un.ebs.core.util.StringUtils;
import com.un.ebs.core.util.WebUtils;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @email 496382223@qq.com
 * @author:Lijj
 * @date: 2019/7/25
 */
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException, SystemException {
        //处理OPEN—API逻辑

        if (request.getRequestURI().startsWith("/open-api/")
                && StringUtils.isNullOrEmpty(request.getHeader("Authorization"))
                && !StringUtils.isNullOrEmpty(request.getParameter("token"))) {
            //通过请求中url 参数token 从redis中换取真实token
            TokenService tokenService = (TokenService) SpringContextUtil.getBean("tokenService");
            String redis_key = request.getParameter("token");
            String token = tokenService.get("NOTIFY_TOKEN_KEY" + ":" + redis_key);
            logger.info("redis_key = " + redis_key);
            HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(request);
            requestWrapper.addHeader("Authorization", token);
            if (!StringUtils.isNullOrEmpty(requestWrapper.getHeader("Authorization"))) {
                setUserContext(requestWrapper, response, chain);
            }
        } else {  //处理正常逻辑
            String header = request.getHeader("Authorization");
            if (StringUtils.isNullOrEmpty(header) || !header.startsWith("Bearer ")) {
                chain.doFilter(request, response);
                return;
            } else {
                setUserContext(request, response, chain);
            }
        }
    }


    private void setUserContext(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException {
        try {
            String token = request.getHeader("Authorization").replace("Bearer ", "");
            Map map = JwtUtils.parseToken(token);
            UsernamePasswordAuthenticationToken scObj = new UsernamePasswordAuthenticationToken(map, null, null);
            SecurityContextHolder.getContext().setAuthentication(scObj);
            chain.doFilter(request, response);
        } catch (ExpiredJwtException ex) {
            WebUtils.sendMessage(response, ErrorCodes.ExpiredJwt, "令牌已过期", null);
        } catch (MalformedJwtException ex) {
            WebUtils.sendMessage(response, ErrorCodes.MalformedJwt, "无效的令牌", null);
        } catch (Exception ex) {
            ex.printStackTrace();
            WebUtils.sendMessage(response, ex.getMessage());
        }
    }
}
